<script setup lang='ts'>
import { useField } from 'vee-validate'
import * as Yup from 'yup'

/**
 * 与V2的不同点：
 * 1、手机邮箱存在同一个页面，不用切tab
 * 2、如果后台开启了手机验证和邮箱验证，那么只需要验证手机号就可以了，邮箱不需要验证，状态为未验证
 */

defineOptions({
  name: 'LoginRegist',
})
definePageMeta({
  layout: 'other',
})

const { showCaptcha, loadingMemberCaptcha } = useAliCaptcha({
  success: () => {
    runRegisterApi()
  },
})

const appStore = useAppStore()
const { brandConfig, isOpenCPFOnRegister } = storeToRefs(useBrandStore())
const route = useRoute()
const router = useRouter()
const { bool: isCode } = useBoolean(false)
const { bool: isCountdown } = useBoolean(false)
const { bool: needSaveFormData, setTrue: setNeedSaveFormDataTrue } = useBoolean(true)
const { bool: isRegBtnLoading, setBool: setIsRegBtnLoading } = useBoolean(false)
const { bool: isRegDeviceNumLoading, setBool: setIsRegDeviceNumLoading } = useBoolean(false)
const { areaCodeOptionsFiltered } = useAreaCode()
const { countryCallingCode } = useIpApi()

const {
  start,
  reset,
} = useCountDown({
  time: 60 * 1000,
  onFinish() {
    isCountdown.value = false
  },
})
const schema = Yup.object().shape({
  username: Yup.string(),
  email: Yup.string(),
  phone: Yup.string(),
  cpf: Yup.string(),
  parentUid: Yup.string(),
})

const birthdayInputRef = ref()
const birthday = ref('')
const q_u = route.query.u ? route.query.u.toString() : ''
const parentUid = ref(q_u)
const parentC = ref(route.query.c ? route.query.c.toString() : '')
const curParams = ref()
const regType = ref('phone')
const areaCode = ref(countryCallingCode.value)
const isPop = ref(false)
const isAgreeUserMsg = ref('')
const psdColor = ref('#FC3C3C')
const showMsg = ref(true)

if (brandConfig.value && brandConfig.value.reg && brandConfig.value.reg.length) {
  const { mail: b_mail, phone: b_phone } = brandConfig.value.reg[0]
  if (b_mail.mail && !b_phone.phone)
    regType.value = 'email'
}

/** 注册配置 */
const brandRegDetail = computed(() => brandConfig.value)
const regConfig = computed(() => brandRegDetail.value && brandRegDetail.value.reg && brandRegDetail.value.reg.length ? brandRegDetail.value.reg[0] : undefined)
const regDetailConfig = computed(() => {
  if (!regConfig.value) {
    return {
      email: false,
      email_validation: false,
      phone: false,
      phone_validation: false,
      username: false,
      birthday_check: false,
    }
  }
  return {
    email: regConfig.value.mail.mail,
    email_validation: regConfig.value.mail.verify,
    phone: regConfig.value.phone.phone,
    phone_validation: regConfig.value.phone.verify,
    username: regConfig.value.username,
    birthday_check: regConfig.value.birthday,
  }
})
const needEmail = computed(() => regDetailConfig.value.email)
const needPhone = computed(() => regDetailConfig.value.phone)
const needUsername = computed(() => regDetailConfig.value.username)
const needCheckEmail = computed(() => regDetailConfig.value.email_validation)
const needCheckPhone = computed(() => regDetailConfig.value.phone_validation)
const needBirthday = computed(() => regDetailConfig.value.birthday_check)

/** 手机注册 */
const isPhoneRegType = computed(() => regType.value === 'phone' && needPhone.value)
/** 邮箱注册 */
const isEmailRegType = computed(() => regType.value === 'email' && needEmail.value)

// #region 表单字段验证
const {
  value: password,
  errorMessage: pwdErrorMsg,
  validate: validatePassword,
  // meta: pwdMeta,
  // resetField: resetPassword,
} = useField<string>('password', (value) => {
  let result
  if (!value)
    result = $t('pop_up_create_account_password_least_8_characters')
  else if (value.length < 8)
    result = $t('pop_up_create_account_password_least_8_characters')
  else if (!upperLowerReg.test(value))
    result = $t('pop_up_create_account_password_uppercase_lowercase_letter')
  else if (!lastOneNumberReg.test(value))
    result = $t('pop_up_create_account_password_least_1_number')
  else
    result = ''
  if (result && result.length)
    setIsRegBtnLoading(false)
  return result
}, { validateOnValueUpdate: false })
const {
  value: email,
  errorMessage: emailErrorMsg,
  validate: validateEmail,
  // setErrors: setEmailErrors,
  setValue: setEmail,
  // resetField: resetEmail,
} = useField<string>('email', (value) => {
  const lastDotIdx = value ? value.lastIndexOf('.') : -1
  let result
  if (!value)
    result = $t('pop_up_create_account_no_support_email')

  else if (!value.includes('@'))
    result = [$t('pop_up_create_account_email_add_char', { delta: '@' })]

  else if (!value.includes('.'))
    result = $t('pop_up_create_account_no_dot_email_add_char', { delta: '.' })

  else if (lastDotIdx === value.length - 1)
    result = $t('pop_up_create_account_no_support_email')

  else if (value === password.value)
    result = $t('email_no_equal_password')

  else if (!emailReg.test(value))
    result = $t('pls_input_email')
  else if (value && value.length > 30)
    result = $t('pls_input_email')
  else
    result = ''

  // 请在您的电邮地址中加入 “@” 符号
  // 请在您的电邮地址中加入 “.” 符号
  // 电子邮件域不受支持
  // 请输入有效的电邮地址
  if (result && result.length)
    setIsRegBtnLoading(false)

  return result
}, { validateOnValueUpdate: false })
const {
  value: phone,
  errorMessage: phoneErrorMsg,
  validate: valiPhone,
  // setErrors: setPhoneError,
  // resetField: resetPhone,
} = useField<string>('phone', (value) => {
  let result
  if (areaCode.value === '+63')
    result = philippinePhoneReg.test(`+63${value}`) && value.length > 5 && value.length <= 18 ? '' : $t('phone_invalid')
  else if (areaCode.value === '+86')
    result = chinaPhoneReg.test(`${value}`) && value.length > 5 && value.length <= 18 ? '' : $t('phone_invalid')
  else if (areaCode.value === '+55')
    result = brazilPhoneReg.test(`+55${value}`) && value.length > 5 && value.length <= 18 ? '' : $t('phone_invalid')
  else
    result = numberReg.test(value) && value.length > 5 && value.length <= 18 ? '' : $t('phone_invalid')
  if (result && result.length)
    setIsRegBtnLoading(false)
  return result
}, { initialValue: '', validateOnValueUpdate: false })
const phoneField = computed(() => `${areaCode.value}-${phone.value}`)
const {
  value: username,
  errorMessage: usernameErrorMsg,
  validate: validateUsername,
  // setErrors: setUsernameErrors,
  setValue: setUsername,
  // resetField: resetUsername,
} = useField<string>('username', (value) => {
  let result
  if (!value)
    result = $t('pop_up_create_account_name_3_char')
  else if (value.length < 6)
    result = $t('pop_up_create_account_name_3_char')
  else if (value.match('[^a-zA-Z0-9_]'))
    result = $t('pop_up_create_an_account_user_name_has_invalid_char')
  else if (value.length > 30)
    result = $t('pop_up_create_account_name_14_char')
  else if (value === password.value)
    result = $t('name_no_equal_pwd')
  else if (!usernameReg2.test(value))
    result = $t('validate_msg_user_name_tip')
  else
    result = ''
  // 此用户名已被使用，请选择另一用户名。
  // 用户名含有无效的字符
  // 您的用户名长度必须为 6 – 30 个字符。
  if (result && result.length)
    setIsRegBtnLoading(false)
  return result
}, { validateOnValueUpdate: false })

const {
  value: verifyCode,
  errorMessage: verifyCodeErrorMsg,
  validate: valiVerifyCode,
  // setValue: setVerifyCode,
} = useField<string>('verifyCode', (value) => {
  if (!value)
    return $t('validate_msg_input_code')
  else if (!payPasswordReg.test(value))
    return isEmailRegType.value ? $t('validate_msg_regexp_code') : $t('validate_msg_regexp_code_phone')
  return ''
}, { validateOnValueUpdate: false })
const {
  value: isAgreeUserAgreement,
  errorMessage: userAgreementErrorMsg,
  validate: valiUserAgreement,
} = useField<boolean>('isAgreeUserAgreement', (value) => {
  if (!value) {
    setIsRegBtnLoading(false)
    return $t('please_agree_and_check_the_user_agreement')
  }

  return ''
}, { initialValue: true, validateOnValueUpdate: false })
// CPF
const { value: cpf, errorMessage: cpfError, validate: valiCPF, setErrors: setCPFError } = useField<string>('cpf', (v) => {
  if (!v)
    return $t('setting_kyc_cpf_input_pls')
  if (!/^\d{11}$/.test(v))
    return $t('format_error')

  return ''
})
// #endregion

const regParams = computed(() => Session.get<IMemberReg>(STORAGE_REG_PARAMS_KEYWORDS)?.value)
if (regParams.value) {
  setEmail(regParams.value.email ?? '', false)
  setUsername(regParams.value.username ?? '', false)
  birthday.value = regParams.value.birthday ?? ''
}
/** 检测是否存在 */
const { runAsync: runExists } = useRequest(ApiMemberExists, {
  onError: (err, params) => {
    console.log(err)
    const ty = params[0].ty
    if (ty === 1) {
      message.error($t('choose_another_name'))
      // setUsernameErrors($t('choose_another_name'))
    }
    else if (ty === 2) {
      message.error($t('email_exists'))
      // setEmailErrors($t('email_exists'))
    }
    else if (ty === 3) {
      message.error($t('phone_exists'))
      // setPhoneError($t('phone_exists'))
    }

    setIsRegBtnLoading(false)
  },
})
/** 检测CPF状态 */
const { runAsync: runAsyncCPFCheck } = useRequest(() => ApiMemberCPFInfo(cpf.value), {
  onError(err) {
    setCPFError(JSON.parse(err.message).data)
    setIsRegBtnLoading(false)
  },
})
/** 发送邮箱验证码 */
const {
  runAsync: runAsyncMemberSendMailCaptcha,
  loading: emailCaptchaLoading,
} = useRequest(() => ApiMemberSendMailCaptcha({ email: email.value }), {
  onSuccess() {
    reset()
    start()
    isCountdown.value = true
    message.success($t('success_send_code'))
  },
})
/** 发送手机验证码 */
const {
  runAsync: runAsyncSendPhoneSms,
  loading: phoneCaptchaLoading,
} = useRequest(() => ApiMemberPhoneSms({ phone: phoneField.value, type: 0 }), {
  onSuccess() {
    reset()
    start()
    isCountdown.value = true
    message.success($t('success_send_code'))
  },
})
/** 注册 */
const {
  run: runMemberReg,
  loading: regLoading,
} = useRequest(ApiMemberReg, {
  manual: true,
  onSuccess: async (res) => {
    await nextTick()
    appStore.setToken(res)
    Local.set('local_regist_token', res)
    Statistics.sendStatisticsCustomEvent(CustomStatisticsEvent.REGISTER, { eventID: `reg-${curParams.value?.username}` })
    message.success(`${$t('tip_pop_up_reg_success_title')} ${curParams.value?.username}!`)
    needSaveFormData.value = false
    Session.remove(STORAGE_REG_PARAMS_KEYWORDS)
    await nextTick()
    i18nNavigateTo('/')
    // closeDialog()
  },
})
const isApiLoading = computed(() => regLoading.value || phoneCaptchaLoading.value || emailCaptchaLoading.value || isRegBtnLoading.value || loadingMemberCaptcha.value || isRegDeviceNumLoading.value)

/** 点击注册按钮 */
async function onRegisterClick() {
  if (needEmail.value) {
    await validateEmail()
  }

  if (needPhone.value)
    await valiPhone()

  if (needUsername.value) {
    await validateUsername()
  }

  await validatePassword()

  if (needBirthday.value) {
    const birthValid = await birthdayInputRef.value.valiBirthday()
    if (birthValid) {
      message.error(birthValid)
      return
    }
    // if (birthValid !== true)
    //   setIsRegBtnLoading(false)
  }

  // 需要CPF时必填
  if (isOpenCPFOnRegister.value)
    await valiCPF()

  await valiUserAgreement()
  if (userAgreementErrorMsg.value) {
    isAgreeUserMsg.value = $t('pls_agree_we_user_agreement')
    showMsg.value = true
    return
  }
  else {
    isAgreeUserMsg.value = ''
    showMsg.value = false
  }

  // 这个不要删：有错误时直接返回，否则重复的邮箱或用户名会因通过格式校验从而进行注册请求
  if (
    (needEmail.value && emailErrorMsg.value)
    || (needPhone.value && phoneErrorMsg.value)
    || usernameErrorMsg.value
    || pwdErrorMsg.value
    || (isOpenCPFOnRegister.value && cpfError.value)
  ) {
    message.error(
      emailErrorMsg.value
      || phoneErrorMsg.value
      || usernameErrorMsg.value as string
      || pwdErrorMsg.value
      || cpfError.value as string,
    )
    setIsRegBtnLoading(false)
    return
  }

  if (isRegBtnLoading.value)
    return
  setIsRegBtnLoading(true)

  if (needPhone.value)
    await onEmailUsernameBlur(3)

  if (needEmail.value)
    await onEmailUsernameBlur(2)

  if (needUsername.value)
    await onEmailUsernameBlur(1)

  if (isOpenCPFOnRegister.value)
    await runAsyncCPFCheck()

  // 需要验证手机
  if (needCheckPhone.value) {
    runAsyncSendPhoneSms().then(() => {
      i18nNavigateTo({ path: '/login/verify', query: {
        v: 'reg',
        t: 'p',
        n: phoneField.value,
      } })
    }).finally(() => {
      setIsRegBtnLoading(false)
    })
    return
  }

  // 需要验证邮箱
  if (needCheckEmail.value) {
    regType.value = 'email'
    runAsyncMemberSendMailCaptcha().then(() => {
      i18nNavigateTo({ path: '/login/verify', query: {
        v: 'reg',
        t: 'e',
        n: email.value,
      } })
    }).finally(() => {
      setIsRegBtnLoading(false)
    })
    return
  }

  setIsRegBtnLoading(false)
  showCaptcha()
}

/** 验证码页面点击提交 */
async function onSubmitClick() {
  await valiVerifyCode()
  if (verifyCodeErrorMsg.value)
    return

  setIsRegBtnLoading(false)
  showCaptcha()
}
/** 进行注册请求 */
async function runRegisterApi() {
  setIsRegDeviceNumLoading(true)
  const paramsReg = {
    username: username.value,
    password: password.value,
    parent_uid: parentUid.value.trim() || q_u || (Local.get(STORAGE_UUUUU)?.value || ''),
    c: parentC.value || (Local.get(STORAGE_CCCCC)?.value || ''),
    device_number: await application.getDeviceNumber(),
    birthday: birthday.value,
    captcha: verifyCode.value,
    cpf_number: cpf.value,
    email: email.value,
    phone: phoneField.value,
  }
  setIsRegDeviceNumLoading(false)

  curParams.value = { ...paramsReg }

  // 如果后台关闭了手机验证，把phone字段去掉
  if (!phone.value)
    delete curParams.value.phone

  if (!needUsername.value) {
    if (isEmailRegType.value)
      curParams.value.username = email.value
    else if (isPhoneRegType.value)
      curParams.value.username = phoneField.value?.replace('+', '').replace('-', '')
  }

  // Session.set(STORAGE_REG_PARAMS_KEYWORDS, paramsReg)
  Session.remove(STORAGE_THIRDREG_PARAMS_KEYWORDS)
  setNeedSaveFormDataTrue()
  console.log('🚸🚸🚸 ~ runRegisterApi ~ 注册传参:', curParams.value)
  runMemberReg(curParams.value)
}

async function onEmailUsernameBlur(type: 1 | 2 | 3) {
  let result
  if (type === 1 && username.value && !usernameErrorMsg.value)
    result = await runExists({ ty: type, val: username.value, noNotify: true })
  if (type === 2 && email.value && !emailErrorMsg.value)
    result = await runExists({ ty: type, val: email.value })
  if (type === 3 && phone.value && !phoneErrorMsg.value)
    result = await runExists({ ty: type, val: phoneField.value, noNotify: true })
  return result
}

function goLogin() {
  i18nNavigateTo('/login/signin')
}
function goPolicies() {
  i18nNavigateTo('/login/policies')
}
function changeBorder(v: string) {
  psdColor.value = v
}
function onBack() {
  router.back()
}
watch(countryCallingCode, (a) => {
  areaCode.value = a
}, { immediate: true })

watch(isApiLoading, (a) => {
  if (a)
    document.body.classList.add('all-style-disabled')
  else
    document.body.classList.remove('all-style-disabled')
})

onMounted(() => {
  appEventBus.on(EventBusNames.REG_VERIFY_EMAIL_OR_PHONE, (v) => {
    verifyCode.value = v
    onSubmitClick()
  })
})
onUnmounted(async () => {
  appEventBus.off(EventBusNames.REG_VERIFY_EMAIL_OR_PHONE, () => {})
  console.log('注册销毁')
  document.body.classList.remove('all-style-disabled')
  if (!needSaveFormData.value) {
    Session.remove(STORAGE_REG_PARAMS_KEYWORDS)
  }
  else {
    // Session.set(STORAGE_REG_PARAMS_KEYWORDS, paramsReg)
    Session.remove(STORAGE_THIRDREG_PARAMS_KEYWORDS)
  }
})

watch(regConfig, (val) => {
  if (val) {
    const { mail: b_mail, phone: b_phone } = val
    if (!b_mail.mail && b_phone.phone)
      regType.value = 'phone'
    else if (b_mail.mail && b_phone.phone)
      regType.value = 'phone'
    else if (!b_mail.mail && !b_phone.phone)
      regType.value = 'phone'
    else if (b_mail.mail && !b_phone.phone)
      regType.value = 'email'
  }
})
</script>

<template>
  <div class="h-full">
    <div class="size-full bg-[#232626]">
      <div class="relative w-full">
        <BaseImage url="/images/webp/header/h5-header.png" alt="" class="w-full aspect-[414/237]" />
        <div class="absolute top-0 w-full flex justify-between items-center p-4">
          <div>logo</div>
          <BaseButton
            class="w-7 !h-7 bg-[rgba(255,255,255,.05)] rounded"
            type="none"
            @click="onBack"
          >
            <BaseIcon name="uni-close2" class="text-xl scale-50" />
          </BaseButton>
        </div>
      </div>

      <div class="py-5 px-6 relative w-full">
        <div class="flex justify-between w-full mb-3">
          <span class="text-base font-extrabold text-white">{{ $t('regist') }}</span>
        </div>
        <div class="mb-3">
          <BaseForm :schema="schema" autocomplete="off" @submit="onRegisterClick">
            <BaseInput
              v-if="needPhone"
              name="phone"
              class="mb-3"
              type="number"
              inputmode="number"
              :model-value="phone"
              :placeholder="$t('pls_type_phone_number')"
              :required="true"
              :tip-msg="$t('pls_confirm_you_type_correct', { type: $t('phone_number') })"
              @update:model-value="v => (phone = v)"
            >
              <template #left-icon>
                <BaseButton type="none" class="text-[0.75rem] !p-0" @click.stop="isPop = true">
                  <div class="border-r-[2px] border-[#e4eaf019] pr-1 flex">
                    {{ areaCode }}<BaseIcon name="uni-arrow-down" class="pl-1" />
                  </div>
                </BaseButton>
              </template>
            </BaseInput>
            <BaseInput
              v-if="needEmail"
              name="email"
              class="mb-3"
              :model-value="email"
              :placeholder="$t('email')"
              :required="true"
              :tip-msg="$t('pls_confirm_you_type_correct', { type: $t('email2') })"
              @update:model-value="v => (email = v)"
            />
            <BaseInput
              v-if="needUsername"
              name="username"
              class="mb-3"
              :model-value="username"
              :placeholder="$t('username_need', [6, 18])"
              :required="true"
              @update:model-value="v => (username = v)"
            />

            <BaseInput
              name="password"
              type="password"
              :required="true"
              :placeholder="$t('password')"
              class="mb-3"
              :style="{ '--bc-input-focus-border-color': psdColor }"
              @update:model-value="v => (password = v)"
            />
            <BasePsdColor v-show="password" :password="password" class="mb-3" @border-color="changeBorder" />
            <BaseInput v-if="isOpenCPFOnRegister" :required="true" name="cpf" max="11" input-mode="numeric" placeholder="CPF" />
            <BaseInputBirthday v-if="needBirthday" ref="birthdayInputRef" v-model="birthday" />
            <div class="w-full my-3">
              <BaseButton type="none" class="h-auto mb-3 text-xs text-[#A8AEB0]" @click="isCode = !isCode">
                <span class="mr-1">{{ $t('type_referral_or_promotional_code') }}</span>
                <BaseIcon name="uni-arrow-down" class="text-base transition duration-300 origin-center" :class="{ 'rotate-180': isCode }" />
              </BaseButton>
              <BaseInput v-if="isCode" name="parentUid" :placeholder="$t('code2')" @update:model-value="v => (parentUid = v)" />
            </div>
            <div class="mb-2">
              <BaseBcGameCheckBox v-model="isAgreeUserAgreement" v-model:show-msg="showMsg" :msg="isAgreeUserMsg">
                <template #label>
                  <div class="flex ml-1 text-[#B3BEC1]">
                    {{ $t('i_am_agree') }}<BaseButton type="none" class="text-xs p-0 mx-1 h-auto text-white" @click="goPolicies">
                      {{ $t('user_protocol') }}
                    </BaseButton>{{ $t('and_confirm_already_eighty') }}
                  </div>
                </template>
              </BaseBcGameCheckBox>
            </div>
            <BaseButton html-type="submit" :loading="isApiLoading" type="primary" class="w-full h-[40px] text-xs">
              {{ $t('regist') }}
            </BaseButton>
            <div class="flex text-white font-extrabold mt-4">
              {{ $t('already_has_account') }}?<BaseButton type="none" class="text-xs p-0 mx-1 h-auto text-[#24EE89]" @click="goLogin">
                {{ $t('signin') }}
              </BaseButton>
            </div>
          </BaseForm>
        </div>
        <div>
          <AppThirdLogin />
        </div>
        <div>
          <BaseBob v-model:show="isPop" v-model:selected="areaCode" is-search :header="$t('area_choice')" :need-move="true" :option="areaCodeOptionsFiltered" />
        </div>
      </div>
    </div>
  </div>
</template>
